package model

import (
	"encoding/json"
	"errors"
	"github.com/starmotioncf/common/constant"
	"github.com/starmotioncf/common/db/field"
	"github.com/starmotioncf/common/restriction"
	"time"
)

// RestrictionRecord 限制记录模型
// 对应数据库表restriction_record
type RestrictionRecord struct {
	ID          int64                    `gorm:"column:id;primaryKey;autoIncrement" json:"id"`               // 主键ID
	Mode        restriction.Mode         `gorm:"column:mode;not null;default:1" json:"mode"`                 // 1黑名单2白名单
	Typ         restriction.Typ          `gorm:"column:typ;not null;default:1" json:"typ"`                   // 对象类型1.ip,2.mac,3.uid
	Val         string                   `gorm:"column:val;not null;size:64" json:"val"`                     // 对象值
	Behaviors   restriction.Behaviors    `gorm:"column:behaviors;not null;default:0" json:"behaviors"`       // 限制行为，1-64位二进制位，每个位代表一种行为
	AddTime     int64                    `gorm:"column:add_time;not null;default:0" json:"add_time"`         // 操作增加时间
	Deadline    int64                    `gorm:"column:deadline;not null;default:0" json:"deadline"`         // 截止时间,必须有值
	TargetUID   uint64                   `gorm:"column:target_uid;not null;default:0" json:"target_uid"`     // 关联的目标用户，可能为0
	Images      field.JSONType[[]string] `gorm:"column:images;type:text;not null" json:"images"`             // mode=1时，证据截图，可以多张图
	ReasonType  restriction.ReasonType   `gorm:"column:reason_type;not null;default:0" json:"reason_type"`   // mode=1时，限制原因类型（1-骚扰，2-涉黄，3-诈骗，4-广告，5-其他
	Remark      string                   `gorm:"column:remark;not null;size:500" json:"remark"`              // 后台操作备注
	PromptMsg   string                   `gorm:"column:prompt_msg;not null;size:500" json:"prompt_msg"`      // mode=1时，直接输出显示给用户的封禁提示消息
	Status      int8                     `gorm:"column:status;not null;default:1" json:"status"`             // 1有效2取消3覆盖
	OperatorUID uint64                   `gorm:"column:operator_uid;not null;default:0" json:"operator_uid"` // 外管操作者id
	CreateBy    int64                    `gorm:"column:create_by;not null;default:0" json:"create_by"`       // 操作人
	UpdateBy    int64                    `gorm:"column:update_by;not null;default:0" json:"update_by"`       // 最后操作人
	CreatedAt   int64                    `gorm:"column:created_at;not null" json:"created_at"`               // 创建时间
	UpdatedAt   int64                    `gorm:"column:updated_at;not null" json:"updated_at"`               // 最后更新时间
}

// TableName 设置表名
func (m RestrictionRecord) TableName() string {
	return "restriction_record"
}

func (m *RestrictionRecord) ToRestriction() *Restriction {
	return &Restriction{
		Id:         m.ID,
		Mode:       m.Mode,
		Typ:        m.Typ,
		Val:        m.Val,
		Behaviors:  m.Behaviors,
		Deadline:   m.Deadline,
		ReasonType: m.ReasonType,
		PromptMsg:  m.PromptMsg,
	}
}

// Restriction 缓存的时候不要存那么多没必要字段,新建一个对象保存
type Restriction struct {
	Id         int64                  `json:"id" gorm:"column:id;primaryKey;autoincrement;"`
	Mode       restriction.Mode       `json:"mode" gorm:"column:mode;default:1"`
	Typ        restriction.Typ        `json:"typ" gorm:"column:typ;default:0"`
	Val        string                 `json:"val" gorm:"column:val;default:"`
	Behaviors  restriction.Behaviors  `json:"behaviors" gorm:"column:behaviors;default:0"`
	Deadline   int64                  `json:"deadline" gorm:"column:deadline;default:0"`       //封禁截止时间，0为解封
	ReasonType restriction.ReasonType `json:"reason_type" gorm:"column:reason_type;default:0"` //封禁原因（0-解封，1-骚扰，2-涉黄，3-诈骗，4-广告，5-其他
	PromptMsg  string                 `json:"prompt_msg" gorm:"column:prompt_msg;default:"`
}

func (m Restriction) MarshalBinary() (data []byte, err error) {
	if m.Deadline == 0 {
		return nil, errors.New("deadline is zero")
	}
	return json.Marshal(m)
}

func (m *Restriction) UnmarshalBinary(data []byte) error {
	if data == nil || len(data) == 0 {
		return nil
	}
	return json.Unmarshal(data, &m)
}

// 封禁截止时间
func (m *Restriction) DeadlineTime() time.Time {
	return time.Unix(m.Deadline, 0)
}

// 是否永久封禁
func (m *Restriction) Forever() bool {
	return m.Deadline == constant.Permanent
}

// BanRemainingTime 封禁剩余时间
func (m *Restriction) BanRemainingTime() time.Duration {
	return time.Unix(m.Deadline, 0).Sub(time.Now())
}

func (m *Restriction) GetMode() restriction.Mode {
	return m.Mode
}

func (m *Restriction) GetTyp() restriction.Typ {
	return m.Typ
}

func (m *Restriction) GetVal() string {
	return m.Val
}

func (m *Restriction) GetBehaviors() restriction.Behaviors {
	return m.Behaviors
}
